package com.dubious.interview.euler.prime;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;

public class FilePrimeIterator extends PrimeIterator {

    private long upperBound;
    private DataInputStream reader;
    
    public FilePrimeIterator(long upperBound) throws IOException
    {
        this.upperBound = upperBound;
        this.reader = new DataInputStream(new BufferedInputStream(new FileInputStream("primes.txt")));
        // I know I am going to pay for this hack later.
        // But the original generation of primes.txt assumed 1 is a prime.  It is not.
        // So we need to skip the first byte.
        reader.read();
    }

    @Override
    protected long nextPrime() {
        try
        {
            int nextByte = reader.read();
            long nextPrime = 0;
            if(nextByte != 0)
            {
                // have case where difference is written in a single byte
                nextPrime = getLastPrime() + nextByte;
            } else
            {
                long nextLong = 0;
                try
                {
                    nextLong = reader.readLong();
                } catch (EOFException e)
                {
                    // end of file
                    return 0;
                }
                
                // have case where difference is written as a long (it is preceded by this 0-value byte)
                nextPrime = getLastPrime() + nextLong;
            }
            
            if(nextPrime >= upperBound)
            {
                // the client no longer wants primes
                return 0;
            }

            return nextPrime;
        } catch(IOException e)
        {
            // this is an unexpected error so we wrap it as a RuntimeException
            throw new RuntimeException("Unexpected could not read primes: ", e);
        }
    }
}
